package com.winning.pmph.utils;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
public class RichEditorFormatClearUtil {

	private static List<String> classList = Lists.newArrayList("contexttype1", "contexttype2", "contexttype3", "contexttype4",
            "borderone", "bordertwo", "borderthree", "borderfour", "borderfive", "jr_text_class_center", "jr_text_class_right",
            "h1", "h2", "h3", "h4", "h5", "h6", "t_title", "t_note", "p_title", "p_note", "v_title", "zt");

	public static String clearFormat(String property, Set<String> eleSet) {
		// 清除office格式，style标签，style样式，span标签
		property = clearoffice(property);
		property = format(property,"",eleSet);
		property = br2p(property);
        return property;
    }

	private static String clearoffice(String input) {
        //删除注释
        input = input.replaceAll("(?s)<\\!\\-\\-.+?\\-\\->", "");
        Document doc = Jsoup.parse(input);
        Elements ops = doc.body().select("o|p");
        ops.remove();
        doc.body().getElementsByTag("v:shape").remove();
        doc.body().getElementsByTag("v:imagedata").remove();
        doc.body().getElementsByTag("v:shapetype").remove();
        doc.body().getElementsByTag("v:stroke").remove();
        // 清洗table样式
        Elements tables = doc.getElementsByTag("table");
		if(tables.size() > 0) {
			for(int j = 0; j < tables.size(); j++) {
			    tables.get(j).getAllElements().forEach(el -> {
			    	String rowspan = el.attr("rowspan");
			    	String colspan = el.attr("colspan");
			    	el.clearAttributes();
			    	if (!(StringUtils.isEmpty(rowspan) || Integer.valueOf(rowspan) == 1)){
						el.attr("rowspan", rowspan);
					}
			    	if (!(StringUtils.isEmpty(colspan) || Integer.valueOf(colspan) == 1)){
						el.attr("colspan", colspan);
					}
			    });
			    tables.get(j).getElementsByTag("td").forEach(td -> td.text(td.text()));
			    tables.get(j).attr("border", "1px solid black");
			}
		}
        //删除style
        doc.body().getAllElements().removeAttr("style");
        //删除style
        Elements styles = doc.body().select("style");
        styles.remove();
        //替换span为#text
        Elements spans = doc.body().select("span");
        for (Element span : spans) {
            span.unwrap();
        }
        Elements as = doc.body().select("a");
        for (Element a : as) {
            a.unwrap();
        }
        doc.body().select("pre").tagName("p");
        doc.body().select("strong").tagName("b");
        doc.body().select("em").tagName("i");
        doc.body().select("div").forEach(d -> {
            // 如果div的class属性以border开头，则改div不删除
            if (StringUtils.isBlank(d.attr("class")) || !(d.attr("class").startsWith("border"))) {
                d.tagName("br");
            }
        });
        return Jsoup.parse(doc.body().html()).body().html();
    }

	private static String format(String input, String md5, Set<String> eleSet) {
        Document doc = Jsoup.parse(input);
        Set<String> paramTag = Stream.of("p", "div", "br").collect(Collectors.toSet());
        for (int i = doc.body().childNodeSize() -1 ; i >=0; i--) {
            Node child = doc.body().childNode(i);
            if (paramTag.contains(child.nodeName().toLowerCase())) {
                continue;
            }
            // 不是换行标签, 判断兄弟节点是否为换行标签；
            else {
                // 外层包裹p标签；
                child.wrap("<p></p>");
                Element parent = (Element)child.parent();
                while(Objects.nonNull(parent.previousSibling())
                        && !paramTag.contains(parent.previousSibling().nodeName())){
                    i--;
                    parent.insertChildren(0, parent.previousSibling());
                }
            }
        }
        for (int i = doc.body().childNodeSize() -1 ; i >=0; i--) {
            Node child = doc.body().childNode(i);
            if (child instanceof Element) {
                Element element = (Element) child;
                // 查找P标签
                if (element.tagName().equalsIgnoreCase("p")) {
                	// 如果P标签内为空，remove   p  标签
                    if (StringUtils.isBlank(element.html())) {
                        child.remove();
                        continue;
                    }
                } else if (element.tagName().equalsIgnoreCase("br")) {
                    element.remove();
                } else if (element.tagName().contains("h")) {
                	element.removeAttr("id");
                	if (element.tagName().equalsIgnoreCase("h1")) {
                        element.tagName("p").addClass("h1");
                    } else if (element.tagName().equalsIgnoreCase("h2")) {
                    	element.tagName("p").addClass("h2");
                    } else if (element.tagName().equalsIgnoreCase("h3")) {
                        element.tagName("p").addClass("h3");
                    } else if (element.tagName().equalsIgnoreCase("h4")) {
                        element.tagName("p").addClass("h4");
                    } else if (element.tagName().equalsIgnoreCase("h5")) {
                        element.tagName("p").addClass("h5");
                    } else if (element.tagName().equalsIgnoreCase("h6")) {
                    	element.tagName("p").addClass("h6");
                    } else if (element.tagName().equalsIgnoreCase("h7")) {
                        element.tagName("p");
                    } else if (element.tagName().equalsIgnoreCase("h8")) {
                        element.tagName("p");
                    } else if (element.tagName().equalsIgnoreCase("h9")) {
                        element.tagName("p");
                    } else if (element.tagName().equalsIgnoreCase("h10")) {
                        element.tagName("p");
                    } else if (element.tagName().equalsIgnoreCase("h11")) {
                        element.tagName("p");
                    } else if (element.tagName().equalsIgnoreCase("h12")) {
                        element.tagName("p");
                    } else {
                    	log.error("【【发现未知h标签】】" + element.tagName());
                    }
                } else if (element.tagName().equalsIgnoreCase("img")) {

                } else if (element.tagName().equalsIgnoreCase("table")) {

                } else {
                	log.error("【【发现未知元素】】" + element.outerHtml());
                    System.out.println("【【发现未知元素】】" + element.outerHtml());
                }
            }
            else if (child.nodeName().equals("#text")) {
                if (StringUtils.isBlank(child.outerHtml())) {
                    child.remove();
                    continue;
                }
                child.wrap("<p></p>");
            }
        }
        // 不明白
        String output = doc.body().html();
        String md5_ = DigestUtils.md5Hex(output);
        if (md5_.equalsIgnoreCase(md5)) {
        	Elements allEle = doc.body().getAllElements();
        	for (Element item : allEle) {
        		if (!(item.attr("class") + "").contains("rw_img") && !classList.contains(item.attr("class"))) {
        			item.removeAttr("class");
        		}
        		eleSet.add(item.tagName());
        		eleSet.add("class:" + item.attr("class"));
        	}
            return doc.body().html();
        }
        return format(output, md5_, eleSet);
    }

	private static String br2p(String input) {
        Document doc = Jsoup.parse(input);
        Elements ps = doc.getElementsByTag("p");
        removeDiv(ps);
        // 去除div里面的br标签
        Elements div = doc.getElementsByTag("div");
        removeDiv(div);
        Elements as = doc.getElementsByTag("a");
        for (Element a : as) {
            a.unwrap();
        }
        // 查找所有的P标签，删除内容是空的P标签
        doc.getElementsByTag("p").forEach(p -> {
        	// 移除p的除class属性和id属性
        	p.attributes().forEach(attr -> {
        		if (StringUtils.isNotBlank(attr.getKey())) {
        			if (!"class".equals(attr.getKey()) && !"id".equals(attr.getKey())) {
            			p.removeAttr(attr.getKey());
            		}
        		}
        	});
        });
        // 移除img的除src,class,title,id属性
        doc.getElementsByTag("img").forEach(img -> {
        	img.attributes().forEach(attr -> {
        		if (StringUtils.isNotBlank(attr.getKey())) {
        			if (!"class".equals(attr.getKey()) && !"id".equals(attr.getKey())
        					&& !"src".equals(attr.getKey()) && !"title".equals(attr.getKey())
                            && !attr.getKey().startsWith("data-")) {
            			img.removeAttr(attr.getKey());
            		}
        		}
        	});
        });
        return Jsoup.parse(doc.body().html()).body().html();
    }

    private static void removeDiv(Elements ps) {
        for (Element p : ps) {
            String[] texts = p.html().split("<br\\s*/?\\s*>");
            if (texts.length > 1) {
                String html = "";
                for (int i = 0; i < texts.length; i++) {
                    String text = texts[i].trim();
                    if (text.length() > 0) {
                        html += "<p>" + texts[i].trim() + "</p>";
                    }
                }
                p.after(html);
                p.remove();
            } else {
                Elements brs = p.select("br");
                brs.remove();
            }
        }
    }

    public static void copyImage(String pathFileName,String storePath,String fileName){
        InputStream inputStream = null;
        FileOutputStream outputStream = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        try {
            url = new URL(pathFileName);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            inputStream = httpUrl.getInputStream();

            // copy地址
            File storeFile = new File(storePath);
            if (!storeFile.exists()) {
                storeFile.mkdirs();
            }
            File file = new File(storeFile + "/" + fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            outputStream = new FileOutputStream(file);
            byte [] bytes = new byte[1024];
            int len = 0;
            while((len = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes,0,len);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("图片上传失败");
        } finally {
            try {
                httpUrl.disconnect();
                inputStream.close();
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
